perm filename UPD.CNV[C,JRA]1 blob sn#019578 filedate 1973-01-10 generic text, type T, neo UTF8



	ON PATTERN DIRECTED INVOCATION
	    Methods can be invoked in association with adding items to,
	fetching items from, and removing items from the data base.  The
	invocation depends on a match between the method's pattern and
	the item, a match being an assignment of values to the pattern's
	variables that will make it EQUAL to the item.  Since when if-
	needed methods are called, it is necessary to match two patterns
	against each other, the matcher always returns a list of two
	alists that specify assignments of as many variables on both
	sides as possible.  If there is no match, NIL is returned.
	    The matcher may be called by (MATCH varpat datapat);  MATCH
	is asymmetric in that it is biased toward assigning variables in
	varpat to constants from the other side.  A pattern is a non-
	circular list structure with "variable parts" marked by the
	prefixes "!>" and "!,".  "!>var" must match a variable-free
	section of datapat.  (This restriction will always be met when
	patterns are matched against items.)  Matching "!>var" against

	something causes var to be bound on the alist for variables in
	varpat, with a value corresponding to what is matched.  For
	example, (MATCH '(FOO !>X) '(FOO BAR)) returns (((X BAR)) NIL).
	(Here, "NIL" is the alist for variables in (FOO BAR).)
	    The matcher is multi-level (that is, variables can occur
	below the top level of list structure), and dots are allowed in
	patterns, as (DINO DESI . !>X).  Hence, the pattern ((FREDS !>X)
	. !>REST) matches






						   PAGE 2


			    ((FREDS FATHER) WHISTLES)
			 ((FREDS FATHER) WHISTLES DIXIE)
			     ((FREDS GONE) HE SAID),
	generating association lists
			 ((X FATHER) (REST (WHISTLES)))
		      ((X FATHER) (REST (WHISTLES DIXIE)))
			  ((X GONE) (REST (HE SAID))),
	respectively.  (The second lists are always NIL in these cases.)
	    When FETCH calls the matcher, it uses the varpat alist to
	make up an item possibility.  Thus, if items (SPIRO SUCKS ROCKS)
	and (SPIRO SUCKS DICK) are present in the current context, (FETCH
	'(SPIRO SUCKS !>WHAT)) might return

	(*POSSIBILITIES *IGNORE 
  (*ITEM ((SPIRO SUCKS ROCKS) (10 +)) ((WHAT ROCKS)))
  (*ITEM ((SPIRO SUCKS DICK) (0 +)) ((WHAT DICK)))).

   TRY-NEXT takes the association lists from item possibilities
	and assigns the variables as they direct.
	    The other principal prefix is "!,", which refers to the
	current binding of its variable in the match so far, or the
	current Conniver binding, and matches its value.  For example,
	the pattern (GRANDFATHER !>X !,X) matches all items corresponding
	to people who are their own grandfathers.
	    Another frill is the ability to specify a restricted match
	If "!>" prefixes a non-atomic expression, its CDR is a list of
	forms that must all evaluate (in Lisp) to non-NIL after






						   PAGE 3


	assignment of its CAR.  For example, !>(X (ATOM !,X)) matches
	only atoms, and !>(CREATURE (FEATHERLESS !,CREATURE) (EQ (NUMBER-
	OF-LEGS !,CREATURE) 2)) matches featherless bipeds.  If it is
	desired to bind and initialize a variable in its pattern's alist,

ne can write "!,(var initial-value)."  For example, (FUNCT-OF
	!>FORM !,(F (CAR !,FORM))) matches (FUNCT-OF (FACTORIAL 5)
	FACTORIAL) but not (FUNCT-OF (PLUS 2 2) MINUS).  Finally, if it
	is desired to specify an item shape without naming or saving its
	parts, the prefix characters "!>" can stand alone.  Thus, (FETCH
	'(FOO !>)) returns a possibilities list of items of the form (FOO
	x), but applying TRY-NEXT to it sets no variables.
	    If-addeds and if-removeds work nicely with MATCH.  To invoke
	one, Conniver applies MATCH to its pattern and the item that
	triggered it.  If the result is non-NIL, the varpat alist is used
	to start the variable bindings in the method's frame (which may
	be augmented by "AUX" bindings).
	    An if-needed method is really an entirely different kind of
	entity.  First, its match occurs at FETCH-time, its alists being
	saved in a *METHOD possibility until TRY-NEXT calls it.  Second,
	such a method is a kind of callable subroutine, which should be
	capable of more than verifying or achieving conditions
	represented by constant patterns.  In particular, one would like
	to be able to specify that a slot represents an output variable,
	to be set by the method but not by the match.  This is
	accomplished by use of the prefix "!<";  "!<var" matches only






						   PAGE 4


	expressions with variables (var being assigned to that
	expression, but only so the user can see what is going to happen
	on output).
	    Thus, when (NOTE (INSTANCE)) is called to create a value to
	be added to the possibilities list, MATCH is called again in a
	special (secret) way, this time with the FETCH-pattern as varpat,
	which treats the method pattern as an essentially constant
	structure whose variable slots are to be filled as indicated by
	the values the variables have picked up in the method.  
	    As an example, consider the method

IF-NEEDED FIND-SUPPORTERS
      (ON !>X !<Y)
     "AUX" ((P (FETCH '(SUPPORTS !>Y !,X))))
LOOP
     (TRY-NEXT P '(ADIEU))
     (AU-REVOIR (INSTANCE))
     (GO 'LOOP)   ).

	This method will appear in a FETCH-possibilities-list generated
	by, e.g., (FETCH '(ON BOX1 !>B)), but not one generated by, e.g.,
	(FETCH '(ON !>A TABLE)), which is looking for "supportees" of an
	object called TABLE.  When FIND-SUPPORTERS is entered, X will
	have the value BOX1, and Y the value !>B.  At statement :LOOP, Y
	is set to the next supporter of BOX1.  One such supporter is
	returned each time the method is entered or re-entered. 
	    Notice that this method has a completely different purpose
	from one with the pattern (ON !<X !>Y), which would find the

supportees" of a given object Y; or one with pattern (ON !>X






						   PAGE 5


	!>Y), which verifies a support relation.
	    Occasionally, however, one wishes the decision of what to do
	in cases differing in this way to be made after the method is
	entered.  In this case, one can use the prefix "!?" which is
	ambiguous; its variable is assigned if and only if it matches a
	variable-free expression.  The complementary ambiguity on the
	FETCH-side is handled by the prefix "!;" which means "!>" if its
	variable is unbound in the current match alist and unassigned by
	Conniver; or "!," if its variable is assigned or bound in the
	match alist but unassigned.  These characters are typically handy
	in situations where a pattern is to be expanded according to its
	definition, regardless of exactly what is variable in it.  For
	example, if men are always to be treated as featherless bipeds,
	the following method does the conversion if one is looking for
	men or attempting to verify that something is a man:

IF-NEEDED IS-MAN
      (IS !?X MAN)
  "AUX" ((P (FETCH '(IS !;X BIPED))))
LOOP
     (TRY-NEXT P '(ADIEU))
     (COND ((PRESENT '(FEATHERLESS !,X))
     (AU-REVOIR (INSTANCE)))   )
     (GO 'LOOP)   ).

t takes the place of the two methods that would be required
	without "!?" and "!;", which would have "!<" and "!>", or "!>"
	and "!," instead.  (Micro-Planner users please note that the
	micro-Planner prefix "$?" includes both ambiguities, and would
	take the place of all prefixes used in IS-MAN.) 






						   PAGE 6


	    Finally, some if-needed methods claim to be able to expand on
	the syntactic forms of calling patterns rather than to be able to
	generate items similar to those represented by those patterns.
	The corresponding method-pattern variables are signaled by the
	prefix "!'", which is analogous to the "'" of CEXPR bound
	variable declarations.  "!'var" binds var to an expression
	without examining its internal structure in any way; its
	variables are neither substituted or bound.  For example, a
	method for causing (FETCH '(AND *conjuncts*)) to set the
	variables in the conjuncts correctly might look like:

IF-NEEDED AND-EXPANDER 
      (AND . !'CONJUNCTS)
     (COND (CONJUNCTS
	"AUX" ((P1 (FETCH (CAR CONJUNCTS)))
	       (P2 (FETCH !"(AND . @(CDR ,CONJUNCTS))))
	       COP2)
     :LOOP1
	(TRY-NEXT P1 '(ADIEU))
	(CSETQ COP2 (COPY P2))
     :LOOP2
	(TRY-NEXT COP2 '(GO 'LOOP1))
	(AU-REVOIR (INSTANCE))
	(GO 'LOOP2))
    ((AU-REVOIR (INSTANCE)))   )).

or example, if the items (GREEN BOX3), (GREEN BOX1), (GREEN
	BOX4), (ON BOX1 BOX2), and (ON BOX4 BOX5) are in the data base,
	repeatedly TRY-NEXTing (FETCH '(AND (GREEN !>X) (ON !,X !>Y)))
	will set X to BOX1 and Y to BOX2, then X to BOX4 and Y to BOX5,
	then quit.  The method's value is always (*NOTE NIL), because it
	never concerns itself with binding calling pattern variables.  (A
	more efficient implementation, by the way, is obviously






						   PAGE 7



	possible.)
	    All the syntactic frills such as restrictions and bound
	variable initialization are legal in method patterns.  However,
	it is generally meaningless to restrict a "!<"-marked variable.
	If !<(X (ATOM !,X)) appears in a pattern, it is not clear what is
	being restricted.  It is certainly not possible by such a
	restriction to prevent future assignments of X to anything
	non-atomic.  All restrictions will be run only at match time.
	In the case of "!?", restrictions will be run only if the prefixed
	variable is assigned in the match.